package de.hska.swlab.iwwdnw.model;

public class Spielfeld {

	/**
	 * 48 Wissensstreiterfelder.
	 * 
	 * 4 (Spieler) * 12 - jeweils das Erste ist das Startfeld eines Spielers.
	 */
	private WissensstreiterFeld[] wissensstreiterFelder;

	/**
	 * Startfelder der Spieler.
	 * 
	 * Feld[Spielernummer][3 Felder]
	 */
	private WissensstreiterHeimatFeld[][] wissensstreiterHeimatFeld;

	/**
	 * Status des Wissensanzeiger der Spieler.
	 * 
	 * Feld[Spielernmmer][4 Kategorien] ist 0 fuer keine Frage richtig und 3
	 * fuer alle richtig beantwortet.
	 */
	private int[][] wissenszeigerStatus;

	/**
	 * Konstruktor
	 * 
	 * @param anzahlSpieler
	 *            Anzahl der teilnehmenden Spieler
	 */
	public Spielfeld(int anzahlSpieler) {
		wissensstreiterFelder = new WissensstreiterFeld[48];

		for (int i = 0; i < 48; i++) {
			wissensstreiterFelder[i] = new WissensstreiterFeld();
		}

		wissensstreiterHeimatFeld = new WissensstreiterHeimatFeld[anzahlSpieler][];
		wissenszeigerStatus = new int[anzahlSpieler][];

		for (int i = 0; i < anzahlSpieler; i++) {
			wissenszeigerStatus[i] = new int[4];
			wissensstreiterHeimatFeld[i] = new WissensstreiterHeimatFeld[3];

			for (int j = 0; j < 3; j++) {
				wissensstreiterHeimatFeld[i][j] = new WissensstreiterHeimatFeld();
				wissensstreiterHeimatFeld[i][j].setWissensstreiterId(j + 1);
			}
		}
	}

	/**
	 * Gibt die Wissenstreiterfeld zurueck
	 * 
	 * @return die Felder auf denen sich Wissenstreiter befinden koennen
	 */
	public WissensstreiterFeld[] getWissensstreiterFelder() {
		return wissensstreiterFelder;
	}

	/**
	 * Gibt die Heimatfelder zurueck
	 * 
	 * @return die Felder die Heimatfelder sind
	 */
	public WissensstreiterHeimatFeld[][] getWissensstreiterHeimatFeld() {
		return wissensstreiterHeimatFeld;
	}

	/**
	 * Gibt den Status des Wissenzeigers zurueck
	 * 
	 * @return den Status eines Wissenzeigers eines Spielers
	 */
	public int[][] getWissenszeigerStatus() {
		return wissenszeigerStatus;
	}

	/**
	 * Gibt den Spieler zurück, dessen Wissenszeiger alle auf 3 (voll) stehen.
	 * 
	 * @return die id des Spielers, sonst -1
	 */
	public int hatSpielerGewonnen() {
		for (int i = 0; i < wissenszeigerStatus.length; i++) {
			int anzahlWissenszeigerVoll = 0;

			for (int j = 0; j < wissenszeigerStatus[i].length; j++) {
				if (wissenszeigerStatus[i][j] == 3) {
					anzahlWissenszeigerVoll++;
				}
			}

			if (anzahlWissenszeigerVoll == 4) {
				return i;
			}
		}

		return -1;
	}

	/**
	 * Ist Zug mit Wissenstreiter moeglich oder nicht
	 * 
	 * @param wissensstreiterId
	 *            Id des Wissensstreiters
	 * @param spieler
	 *            Id des aktuellen Spielers
	 * @param wurf
	 *            aktueller Wurf
	 * @return true wenn moeglich, sonst false
	 */
	public boolean wissensstreiterZugMoeglich(int wissensstreiterId,
			int spieler, int wurf) {
		// steht Wissensstreiter auf dem Startfeld
		for (int i = 0; i < wissensstreiterHeimatFeld[spieler].length; i++) {
			if (wissensstreiterHeimatFeld[spieler][i].getWissensstreiterId() == wissensstreiterId) {
				return wurf == 6
						&& wissensstreiterFelder[spieler * 12].getSpieler() != spieler;
			}
		}

		// steht Wissensstreiter auf dem Spielfeld
		for (int i = 0; i < wissensstreiterFelder.length; i++) {
			if (wissensstreiterFelder[i].getWissenstreiterId() == wissensstreiterId
					&& wissensstreiterFelder[i].getSpieler() == spieler) {
				return wissensstreiterFelder[(i + wurf) % 48].getSpieler() != spieler;
			}
		}

		return false;
	}

	/**
	 * Bewegt einen Wissensstreiter
	 * 
	 * @param wissensstreiterId
	 *            Id des Wissensstreiters
	 * @param spieler
	 *            Id des aktuellen Spielers
	 * @param wurf
	 *            aktueller Wurf
	 * @return das Feld auf dem der kollidierte Spieler steht, sonst null
	 */
	public WissensstreiterFeld wissensstreiterBewegen(int wissensstreiterId,
			int spieler, int wurf) {
		// steht Wissensstreiter auf dem Startfeld
		for (int i = 0; i < wissensstreiterHeimatFeld[spieler].length; i++) {
			if (wissensstreiterHeimatFeld[spieler][i].getWissensstreiterId() == wissensstreiterId) {
				WissensstreiterFeld kollidierenderSpieler = null;

				if (wissensstreiterFelder[12 * spieler].getSpieler() != -1) {
					kollidierenderSpieler = wissensstreiterFelder[12 * spieler];
					wissensstreiterFelder[12 * spieler] = new WissensstreiterFeld();
				}

				wissensstreiterHeimatFeld[spieler][i].setWissensstreiterId(0);
				wissensstreiterFelder[12 * spieler]
						.setWissenstreiterId(wissensstreiterId);
				wissensstreiterFelder[12 * spieler].setSpieler(spieler);

				return kollidierenderSpieler;
			}
		}

		// steht Wissensstreiter auf dem Spielfeld
		for (int i = 0; i < wissensstreiterFelder.length; i++) {
			if (wissensstreiterFelder[i].getWissenstreiterId() == wissensstreiterId
					&& wissensstreiterFelder[i].getSpieler() == spieler) {
				WissensstreiterFeld kollidierendesFeld = null;

				if (wissensstreiterFelder[(i + wurf) % 48].getSpieler() != -1) {
					kollidierendesFeld = wissensstreiterFelder[(i + wurf) % 48];
					wissensstreiterFelder[(i + wurf) % 48] = new WissensstreiterFeld();
				}

				wissensstreiterFelder[i].setSpieler(-1);
				wissensstreiterFelder[i].setWissenstreiterId(0);
				wissensstreiterFelder[(i + wurf) % 48].setSpieler(spieler);
				wissensstreiterFelder[(i + wurf) % 48]
						.setWissenstreiterId(wissensstreiterId);

				return kollidierendesFeld;
			}
		}

		return null;
	}

	/**
	 * Behandelt die Kollission zweier Wissensstreiter und die Umplatzierung
	 * derer je nach gegebener Antwort auf die gestellte Frage
	 * 
	 * @param spieler
	 *            aktueller Spieler der am Zug ist
	 * @param wissensstreiterId
	 *            Id des Wissensstreiters des Spielers
	 * @param feld
	 *            das Feld auf dem der kollidierte Spieler steht
	 * @param istRichtig
	 *            true wenn die gegebene Antwort richtig ist, sonst false
	 */
	public void wissensstreiterKollisionMitFrageBeantworten(int spieler,
			int wissensstreiterId, WissensstreiterFeld feld, boolean istRichtig) {
		for (int i = 0; i < wissensstreiterFelder.length; i++) {
			if (wissensstreiterFelder[i].getSpieler() == spieler
					&& wissensstreiterFelder[i].getWissenstreiterId() == wissensstreiterId) {
				if (!istRichtig
						|| wissensstreiterFelder[feld.getSpieler() * 12]
								.getSpieler() >= 0) {
					for (int j = 0; j < wissensstreiterHeimatFeld[feld
							.getSpieler()].length; j++) {
						if (wissensstreiterHeimatFeld[feld.getSpieler()][j]
								.getWissensstreiterId() == 0) {
							wissensstreiterHeimatFeld[feld.getSpieler()][j]
									.setWissensstreiterId(feld
											.getWissenstreiterId());
							break;
						}
					}
				} else {
					wissensstreiterFelder[feld.getSpieler() * 12]
							.setSpieler(feld.getSpieler());
					wissensstreiterFelder[feld.getSpieler() * 12]
							.setWissenstreiterId(feld.getWissenstreiterId());
				}

				break;
			}
		}
	}

	/**
	 * Prueft ob der Zug mit dem Wissenszeiger moeglich ist
	 * 
	 * @param wissenszeigerId
	 *            Id des Wissenszeigers
	 * @param momentanerSpieler
	 *            Id des aktuellen Spielers
	 * @return true wenn moeglich, sonst false
	 */
	public boolean wissenszeigerZugMoeglich(int wissenszeigerId,
			int momentanerSpieler) {
		return wissenszeigerStatus[momentanerSpieler][wissenszeigerId] < 3;
	}

	/**
	 * Erhoeht oder erniedrigt den Wissesnzeiger. Er kann nie kleiner als 0
	 * werden
	 * 
	 * @param wissenszeigerId
	 *            Id des Wissenszeigers
	 * @param momentanerSpieler
	 *            Id des aktuellen Spielers
	 * @param anzahl
	 *            die Anzahl um die der WZ bewegt werden soll
	 */
	public void wissenszeigerBewegen(int wissenszeigerId,
			int momentanerSpieler, int anzahl) {
		wissenszeigerStatus[momentanerSpieler][wissenszeigerId] += anzahl;

		if (wissenszeigerStatus[momentanerSpieler][wissenszeigerId] < 0) {
			wissenszeigerStatus[momentanerSpieler][wissenszeigerId] = 0;
		}
	}

	/**
	 * Prueft ob alle Heimatfelder eines Spielers besetzt sind
	 * 
	 * @param spieler
	 *            Id des Spielers
	 * @return true wenn alle besetzt sind, sonst false
	 */
	public boolean sindAlleHeimatfelderBesetzt(int spieler) {
		for (WissensstreiterHeimatFeld f : wissensstreiterHeimatFeld[spieler]) {
			if (f.getWissensstreiterId() <= 0) {
				return false;
			}
		}

		return true;
	}
}
